package com.juneyaoair.search.service.impl;

import com.juneyaoair.search.entity.GmtMessageResDTO;
import com.juneyaoair.search.entity.MessageEntity;
import com.juneyaoair.search.global.ElasticGlobal;
import com.juneyaoair.search.response.PageResponse;
import com.juneyaoair.search.response.ResponseResult;
import com.juneyaoair.search.service.ElasticService;
import com.juneyaoair.search.utils.ElasticUtil;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 信息检索 查询
 * @author :master
 * @date :20200911
 */
@Service
public class ElasticServiceImpl implements ElasticService {

    private final static Logger log = LoggerFactory.getLogger(ElasticServiceImpl.class);

    @Autowired
    private RestHighLevelClient client;

    /**
     * 参数处理
     * @param messageEntity 参数
     * @return 返回
     */
    private QueryBuilder dealQueryBuilders (MessageEntity messageEntity){
        QueryBuilder queryBuilders = null;
        QueryBuilder queryBuilders1 = null;
        QueryBuilder queryBuilders2 = null;
        QueryBuilder queryBuilders3 = null;
        QueryBuilder queryBuilders4 = null;
        QueryBuilder queryBuilders5 = null;

        /** 很蠢的方法 */
        if (StringUtils.isNotBlank(messageEntity.getSmsContent())) {
            queryBuilders1 = QueryBuilders.matchPhraseQuery(ElasticGlobal.SMS_CONTENT, messageEntity.getSmsContent());
        }
        if (StringUtils.isNotBlank(messageEntity.getToMobile())) {
            queryBuilders2 = QueryBuilders.termQuery(ElasticGlobal.TO_MOBILE, messageEntity.getToMobile());
        }
        if (StringUtils.isNotBlank(messageEntity.getRemark1())) {
            queryBuilders3 = QueryBuilders.termQuery(ElasticGlobal.REMARK1, messageEntity.getRemark1());
        }

        if (StringUtils.isNotBlank(messageEntity.getStartTime())) {
            queryBuilders4 = QueryBuilders.rangeQuery(ElasticGlobal.SEND_TIME).gte(messageEntity.getStartTime());
        }
        if (StringUtils.isNotBlank(messageEntity.getEndTime())) {
            queryBuilders5 = QueryBuilders.rangeQuery(ElasticGlobal.SEND_TIME).lte(messageEntity.getEndTime());
        }

        if (queryBuilders1 != null && queryBuilders2 != null && queryBuilders3 != null && queryBuilders4 != null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1)
                    .must(queryBuilders2)
                    .must(queryBuilders3)
                    .must(queryBuilders4)
                    .must(queryBuilders5);

        }else if (queryBuilders1 != null && queryBuilders2 != null && queryBuilders3 != null && queryBuilders4 != null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1)
                    .must(queryBuilders2)
                    .must(queryBuilders3)
                    .must(queryBuilders4);

        }else if (queryBuilders1 != null && queryBuilders2 != null && queryBuilders3 != null && queryBuilders4 == null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1)
                    .must(queryBuilders2)
                    .must(queryBuilders3);

        }else if (queryBuilders1 != null && queryBuilders2 != null && queryBuilders3 == null && queryBuilders4 == null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1)
                    .must(queryBuilders2);

        }else if (queryBuilders1 != null && queryBuilders2 == null && queryBuilders3 == null && queryBuilders4 == null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1);
        }else if (queryBuilders1 == null && queryBuilders2 == null && queryBuilders3 == null && queryBuilders4 == null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.matchAllQuery();
        }else if (queryBuilders1 != null && queryBuilders2 == null && queryBuilders3 != null && queryBuilders4 == null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1)
                    .must(queryBuilders3);
        }else if (queryBuilders1 != null && queryBuilders2 == null && queryBuilders3 != null && queryBuilders4 != null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1)
                    .must(queryBuilders3)
                    .must(queryBuilders4);
        }else if (queryBuilders1 != null && queryBuilders2 == null && queryBuilders3 != null && queryBuilders4 != null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1)
                    .must(queryBuilders3)
                    .must(queryBuilders4)
                    .must(queryBuilders5);
        }else if (queryBuilders1 != null && queryBuilders2 != null && queryBuilders3 == null && queryBuilders4 != null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1)
                    .must(queryBuilders2)
                    .must(queryBuilders4)
                    .must(queryBuilders5);
        }else if (queryBuilders1 != null && queryBuilders2 != null && queryBuilders3 == null && queryBuilders4 == null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1)
                    .must(queryBuilders2)
                    .must(queryBuilders5);
        }else if (queryBuilders1 != null && queryBuilders2 != null && queryBuilders3 != null && queryBuilders4 == null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1)
                    .must(queryBuilders2)
                    .must(queryBuilders3)
                    .must(queryBuilders5);
        }else if (queryBuilders1 != null && queryBuilders2 == null && queryBuilders3 == null && queryBuilders4 == null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1)
                    .must(queryBuilders5);
        }else if (queryBuilders1 != null && queryBuilders2 == null && queryBuilders3 == null && queryBuilders4 != null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1)
                    .must(queryBuilders4)
                    .must(queryBuilders5);
        }else if (queryBuilders1 != null && queryBuilders2 == null && queryBuilders3 == null && queryBuilders4 != null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders1)
                    .must(queryBuilders4);
        }else if (queryBuilders1 == null && queryBuilders2 != null && queryBuilders3 != null && queryBuilders4 != null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders2)
                    .must(queryBuilders3)
                    .must(queryBuilders4)
                    .must(queryBuilders5);
        }else if (queryBuilders1 == null && queryBuilders2 != null && queryBuilders3 != null && queryBuilders4 != null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders2)
                    .must(queryBuilders3)
                    .must(queryBuilders4);
        }else if (queryBuilders1 == null && queryBuilders2 != null && queryBuilders3 != null && queryBuilders4 == null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders2)
                    .must(queryBuilders3);
        }else if (queryBuilders1 == null && queryBuilders2 != null && queryBuilders3 == null && queryBuilders4 != null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders2)
                    .must(queryBuilders4);
        }else if (queryBuilders1 == null && queryBuilders2 != null && queryBuilders3 == null && queryBuilders4 != null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders2)
                    .must(queryBuilders4)
                    .must(queryBuilders5);
        }else if (queryBuilders1 == null && queryBuilders2 != null && queryBuilders3 == null && queryBuilders4 == null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders2)
                    .must(queryBuilders5);
        }else if (queryBuilders1 == null && queryBuilders2 != null && queryBuilders3 == null && queryBuilders4 == null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders2);
        }else if (queryBuilders1 == null && queryBuilders2 == null && queryBuilders3 != null && queryBuilders4 == null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders3);
        }else if (queryBuilders1 == null && queryBuilders2 == null && queryBuilders3 != null && queryBuilders4 != null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders3)
                    .must(queryBuilders4);
        }else if (queryBuilders1 == null && queryBuilders2 == null && queryBuilders3 != null && queryBuilders4 == null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders3)
                    .must(queryBuilders5);
        }else if (queryBuilders1 == null && queryBuilders2 == null && queryBuilders3 != null && queryBuilders4 != null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders3)
                    .must(queryBuilders4)
                    .must(queryBuilders5);
        }else if (queryBuilders1 == null && queryBuilders2 == null && queryBuilders3 == null && queryBuilders4 != null && queryBuilders5 == null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders4);
        }else if (queryBuilders1 == null && queryBuilders2 == null && queryBuilders3 == null && queryBuilders4 != null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders4)
                    .must(queryBuilders5);
        }else if (queryBuilders1 == null && queryBuilders2 == null && queryBuilders3 == null && queryBuilders4 == null && queryBuilders5 != null) {
            queryBuilders = QueryBuilders.boolQuery()
                    .must(queryBuilders5);
        }
        return queryBuilders;
    }


    @Override
    public ResponseResult messageQuery(MessageEntity messageEntity) {

        ResponseResult response = new ResponseResult();
        PageResponse page = new PageResponse();
        page.setPageIndex(messageEntity.getPageIndex());
        try {
            QueryBuilder queryBuilders = dealQueryBuilders(messageEntity);
            if(null!=queryBuilders){
                SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilders, messageEntity.getPageIndex(), messageEntity.getPageCount());
                //设置返回指定字段
                searchSourceBuilder.fetchSource(ElasticGlobal.FIELD_REQUIRED, null);
                // 指定检索的索引
                SearchRequest request = new SearchRequest(ElasticGlobal.INDEX_NAME);
                request.source(searchSourceBuilder);
                SearchResponse searchResponse = client.search(request);
                SearchHit[] hits = searchResponse.getHits().getHits();
                List<GmtMessageResDTO> res = new ArrayList<>(hits.length);
                GmtMessageResDTO gmtMessageResDTO = null;
                // 查询结果处理 数据类型转化
                SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                for (SearchHit hit : hits) {
                    gmtMessageResDTO = new GmtMessageResDTO();
                    gmtMessageResDTO.setSmsContent((String)hit.getSourceAsMap().get("sms_content"));
                    gmtMessageResDTO.setStatus((String)hit.getSourceAsMap().get("status"));
                    gmtMessageResDTO.setToMobile((String)hit.getSourceAsMap().get("to_mobile"));
                    Date date =  new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse((String)hit.getSourceAsMap().get("send_time") );
                    gmtMessageResDTO.setSendTime(format.format(date));
                    res.add(gmtMessageResDTO);
                }
                page.setList(res);
                // 总共条数
                Long total =  searchResponse.getHits().getTotalHits();
                Long pageCount  = (total + messageEntity.getPageCount() - 1) / messageEntity.getPageCount();
                page.setTotal(total);
                page.setPageTotal(pageCount);
                response.setData(page);
            }
        } catch (Exception e) {
            response.setCode("-1");
            response.setMessage("服务忙，请稍后再试");
            log.error("查询数据异常，metadataVo={},异常信息={}", messageEntity.toString(), e.getMessage());
        }
        return response;
    }

}
